package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

import static java.nio.file.Files.move;

/**
 * @author Mr.M
 * @version 1.0
 * @description 课程计划service接口实现类
 * @date 2022/9/9 11:14
 */
@Service
public class TeachplanServiceImpl implements TeachplanService {

    @Autowired
    private TeachplanMapper teachplanMapper;
    @Autowired
    private TeachplanMediaMapper teachplanMediaMapper;

    /**
     * 查询课程计划
     * @param courseId 课程id
     * @return
     */
    @Override
    public List<TeachplanDto> findTeachplanTree(long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    /**
     * 新增课程计划
     * @param teachplanDto 课程计划信息
     */
    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {

        //课程计划id
        Long id = teachplanDto.getId();
        //修改课程计划
        if (id != null) {
            // id不为空，说明已有课程计划，该接口操作为修改课程计划（即编辑）
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(teachplanDto, teachplan);
            teachplanMapper.updateById(teachplan);
        } else {
            // id为空，说明是新增课程计划
            //取出同父同级别的课程计划数量
            int count = getMaxOrderBy(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();
            //设置排序号
            teachplanNew.setOrderby(count + 1);
            BeanUtils.copyProperties(teachplanDto, teachplanNew);
            teachplanMapper.insert(teachplanNew);
        }
    }


    /**
     * @param courseId 课程id
     * @param parentId 父课程计划id
     * @return int 最新排序号
     * @description 获取最新的排序号
     * @author Mr.M
     * @date 2022/9/9 13:43
     */
    private int getMaxOrderBy(long courseId, long parentId) {
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Teachplan::getOrderby)
                .eq(Teachplan::getCourseId, courseId)
                .eq(Teachplan::getParentid, parentId)
                .orderByDesc(Teachplan::getOrderby)  // 按orderby倒序
                .last("LIMIT 1");  // 只取第一条（即最大值）
        Teachplan teachplan = teachplanMapper.selectOne(queryWrapper);
        // 处理结果
        return teachplan != null ? teachplan.getOrderby() : 0;
    }

    /**
     * 删除课程计划信息
     * @param id
     */
    @Override
    @Transactional
    public void deleteTeachplan(Long id) {
        //根据id查找课程计划
        Teachplan teachplan = teachplanMapper.selectById(id);
        //判断是否为一级信息
        if(teachplan.getGrade() == 1 && teachplan.getParentid() == 0){
            //判断是否有二级信息
            int count = teachplanMapper.selectSecondTeachPlan(id);
            if(count > 0){
                //存在二级信息，抛出异常
                throw new XueChengPlusException("课程计划信息存在子信息，请删除子信息后再操作！");
            }
            //不存在二级信息，直接删除信息
            teachplanMapper.deleteById(id);
            return;
        }
        //如果是二级信息，若有对应的视频信息，先删除视频信息，再删除二级信息
        TeachplanMedia teachplanMedia = teachplanMediaMapper.selectOne(new LambdaQueryWrapper<TeachplanMedia>()
                .eq(TeachplanMedia::getTeachplanId,id));
        if(teachplanMedia != null){
            teachplanMediaMapper.deleteById(teachplanMedia.getId());
        }
        //删除视频信息后再删除二级信息
        teachplanMapper.deleteById(id);
    }

    /**
     * 移动课程计划排序
     * @param id
     * @param moveType
     */
    @Override
    public void moveTeachPlan(Long id, String moveType) {
        // 数据合法性校验
        if(StringUtils.isBlank(moveType) || id == null){
            throw new XueChengPlusException("课程计划id为空或移动类型为空");
        }
        if(!"moveup".equals(moveType) && !"movedown".equals(moveType)){
            throw new XueChengPlusException("课程移动参数传递有误");
        }
        Teachplan teachplan = teachplanMapper.selectById(id);
        Integer grade = teachplan.getGrade();
        if(grade == 1){
            //大章节
            LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Teachplan::getCourseId, teachplan.getCourseId())
                    .eq(Teachplan::getParentid,0L)
                    .orderByAsc(Teachplan::getOrderby);
            List<Teachplan> teachplanList = teachplanMapper.selectList(lambdaQueryWrapper);
            //移动
            move(teachplanList,teachplan,moveType);
        }else{
            //小章节
            LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Teachplan::getCourseId, teachplan.getCourseId())
                    .eq(Teachplan::getParentid,teachplan.getParentid())
                    .orderByAsc(Teachplan::getOrderby);
            List<Teachplan> teachplanList = teachplanMapper.selectList(lambdaQueryWrapper);
            //移动
            move(teachplanList,teachplan,moveType);
        }
    }


    private void move(List<Teachplan> teachplanList, Teachplan teachplan, String moveType) {
        //获取当前课程计划的索引
        int index = teachplanList.indexOf(teachplan);
        //获取当前课程计划的排序值
        Integer orderby = teachplan.getOrderby();
        //判断移动类型
        if("moveup".equals(moveType)){
            //上移
            if(index == 0){
                throw new XueChengPlusException("当前课程计划已在顶端，无法上移");
            }
            Teachplan lastTeachPlan = teachplanList.get(index - 1);
            Integer lastOrderBy = lastTeachPlan.getOrderby();
            lastTeachPlan.setOrderby(orderby);
            teachplan.setOrderby(lastOrderBy);

            //更新
            teachplanMapper.updateById(teachplan);
            teachplanMapper.updateById(lastTeachPlan);
        }else{
            //下移
            if(index == teachplanList.size() - 1){
                throw new XueChengPlusException("当前课程计划已在底端，无法下移");
            }
            Teachplan fistTeachPlan = teachplanList.get(index + 1);
            Integer lastOrderBy = fistTeachPlan.getOrderby();
            fistTeachPlan.setOrderby(orderby);
            teachplan.setOrderby(lastOrderBy);

            //更新
            teachplanMapper.updateById(teachplan);
            teachplanMapper.updateById(fistTeachPlan);
        }
    }


    @Transactional
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XueChengPlusException.cast("教学计划不存在");
        }
        Integer grade = teachplan.getGrade();
        if(grade != 2){
            XueChengPlusException.cast("只允许第二级教学计划绑定媒资文件");
        }
        //课程id
        Long courseId = teachplan.getCourseId();

        //先删除原来该教学计划绑定的媒资
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId,teachplanId));

        //再添加教学计划与媒资的绑定关系
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }

    @Override
    public void unbindMedia(Long teachPlanId, String mediaId) {
        if(teachPlanId == null || mediaId == null){
            XueChengPlusException.cast("课程计划id为空或媒资id为空");
        }
        TeachplanMedia teachplanMedia = teachplanMediaMapper.selectOne(
                new LambdaQueryWrapper<TeachplanMedia>()
                .eq(TeachplanMedia::getMediaId, mediaId)
                .eq(TeachplanMedia::getTeachplanId, teachPlanId));
        Long id = teachplanMedia.getId();
        if(id == null){
            XueChengPlusException.cast("查询失败，id为空");
        }
        teachplanMediaMapper.deleteById(id);
    }
}